package com.ruoyi.videoHandler;

import com.ruoyi.common.utils.AliOssUtils;
import com.ruoyi.historyVideo.domain.HistoryVideo;
import com.ruoyi.historyVideo.service.IHistoryVideoService;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.BinaryMessage;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import javax.imageio.ImageIO;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * @projectName: intelligent-monitor
 * @package: org.ruoyi
 * @className: VideoStreamHandler
 * @author: 寇耕耀
 */
@Component
@ServerEndpoint(value = "/videoStream")
public class VideoStreamHandler extends TextWebSocketHandler {
    private static Session session2;
    //    private final CanvasFrame previewCanvas = new CanvasFrame("摄像头预览");
    private final Java2DFrameConverter converter = new Java2DFrameConverter();
    private List<BufferedImage> bufferedImages;
    @Autowired
    private IHistoryVideoService historyVideoService;

    public static void setSession2(Session session2) {
        System.out.println("session2已设置：");
        System.out.println(session2);
        VideoStreamHandler.session2 = session2;
        System.out.println(VideoStreamHandler.session2);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        session.close();
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
//        System.out.println();
        System.out.println(LocalDateTime.now());
        System.out.println("收到1回应数据" + message);
        // 这里可以处理接收到的文本消息，但在这个场景下可以忽略
    }

    private void init() {
        bufferedImages = new ArrayList<>();
//        previewCanvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
//        previewCanvas.setVisible(true);
//        previewCanvas.setAlwaysOnTop(true);
    }

    @Override
    protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) {
        if (session2 != null) {
            System.out.println("session2不为空");
            try {
                session2.getBasicRemote().sendBinary(message.getPayload());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } else {
            System.out.println("session2为空");
        }

        BufferedImage image = byteArrayToImage(message.getPayload().array());
//        Frame frame = converter.getFrame(byteArrayToImage(message.getPayload().array()));
//        System.out.println(frame);
        bufferedImages.add(image);
        System.out.println(bufferedImages.size());
        if (bufferedImages.size() > 30 * 60 * 60 * 24) {
            try {
                recordImage(bufferedImages, 0L);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            bufferedImages.clear();
        }
        // 如果图像转换成功，则将其转换为Frame对象
//        previewCanvas.showImage(image);
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("连接开始");
        session.sendMessage(new TextMessage("start"));
        init();
        // 连接建立后，可以在这里准备接收流数据
    }

    private BufferedImage byteArrayToImage(byte[] bytes) {
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        // 使用 ImageIO 读取 InputStream 并创建 BufferedImage
        BufferedImage bufferedImage = null;
        try {
            bufferedImage = ImageIO.read(bais);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bufferedImage;
    }

    private void recordImage(List<BufferedImage> imageList, Long id) throws IOException, InterruptedException {
        System.out.println("record调用");
        System.out.println("收到List:" + imageList);
        if (imageList == null || imageList.isEmpty()) {
            return;
        }
        System.out.println("record记录");
        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String fileName = id + "&" + time + ".mp4";

//        设置视频参数:mp4,30帧
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("E:\\" + fileName, imageList.get(0).getWidth(), imageList.get(0).getHeight());
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        recorder.setFormat("mp4");
        recorder.setFrameRate(30);
        recorder.start();

//        将每一帧写入到MP4文件中
        for (BufferedImage image : imageList) {
            recorder.record(converter.getFrame(image));
        }

//        停止录制并释放资源
        recorder.stop();
        recorder.release();

        Thread.sleep(2000);

        String url = AliOssUtils.uploadFile(fileName, Files.newInputStream(Paths.get("E:\\" + fileName)));
        HistoryVideo historyVideo = new HistoryVideo();
        historyVideo.setVideoAddr(url);
        historyVideoService.insertHistoryVideo(historyVideo);
    }

}
